package com.qf.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.nio.file.AccessDeniedException;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component
public class JwtUtils {
    @Value("${token.header}")
    private String header;
    @Value("${token.secret}")
    private String secret;
    @Value("${token.expireTime}")
    private int expireTime;
    @Autowired
    private RedisUtil reidsUtil;
    //生成Jwt
    public String createJwt(Map<String, Object> claims){
        //签名算法
        SignatureAlgorithm hs256 = SignatureAlgorithm.HS256;
        //构造Jwt
        JwtBuilder builder = Jwts.builder()//设置头
                .setClaims(claims)//设置载荷
                //.setExpiration(new Date(System.currentTimeMillis()+expireTime*1000*60))//设置过期时间
                .signWith(hs256,secret);//设置签名
        return builder.compact();
    }
    //解析Jwt,如果不符合报异常
    public Claims parseJwt(String jsonWebToken){
        try{
            Claims claims = Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(jsonWebToken).getBody();
            return claims;
        }catch (Exception e){
            throw new RuntimeException(e.getMessage());
        }
    }
    //从请求头中获得令牌
    public String getToken(HttpServletRequest request){
        String token = request.getHeader(header);
        if(StringUtils.hasText(token)){
            return token;
        }
        return null;
    }
    //验证token，此次登录有没有超时
    public void validateToken(String token) throws AccessDeniedException {
        Claims claims=Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token).getBody();
        Object uuid = claims.get("uuid");
        Object redisToken = reidsUtil.getCacheObject("user:key:" + uuid);
        if(redisToken==null||!redisToken.equals(token)){
            throw new AccessDeniedException("验证失败");
        }
    }
    //刷新令牌时间
    public void refreshToken(String token){
        Claims claims=Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token).getBody();
        Object uuid = claims.get("uuid");
        //保存到redis
        reidsUtil.setCacheObject("user:key:"+uuid,token,expireTime, TimeUnit.SECONDS);
    }

}
